package com.kevin.epacms.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.kevin.epacms.constant.CommonConstant;
import com.kevin.epacms.entity.Notice;
import com.kevin.epacms.entity.dto.NoticeDto;
import com.kevin.epacms.entity.vo.ConditionVo;
import com.kevin.epacms.mapper.NoticeMapper;
import com.kevin.epacms.service.NoticeService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.kevin.epacms.util.PageList;
import com.kevin.epacms.util.Result;
import com.kevin.epacms.util.SearchUtil;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.locks.ReentrantLock;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author kevin
 * @since 2022-11-10
 */
@Service
public class NoticeServiceImpl extends ServiceImpl<NoticeMapper, Notice> implements NoticeService {
    public static final String MD = "md";
    private final ReentrantLock lock = new ReentrantLock();
    @Override
    public Result getNoticeById(Integer id, String type) {
        Notice notice;
        if (StrUtil.equals(type, MD)){
            notice = lambdaQuery()
                    .eq(Notice::getId, id)
                    .select(Notice.class, field -> !StrUtil.equals("detail_html",field.getColumn()))
                    .one();
        }else{
            // 读-写并发问题，加锁
            lock.lock();
            try{
                notice = lambdaQuery()
                        .eq(Notice::getId, id)
                        .select(Notice.class, field -> !StrUtil.equals("detail_md",field.getColumn()))
                        .one();
                // 前台访问点击数+1
                lambdaUpdate().set(Notice::getClickNum, notice.getClickNum() + 1)
                        .eq(Notice::getId, id)
                        .eq(Notice::getClickNum, notice.getClickNum())
                        .update();
            }finally {
                lock.unlock();
            }
        }
        return Result.ok(notice);
    }

    @Override
    public Result addOrUpdateNotice(Notice notice) {
        if (Objects.nonNull(notice.getId())){
            notice.setCreateTime(LocalDateTime.now());
        }
        return saveOrUpdate(notice) ? Result.ok(CommonConstant.SUCCESS) : Result.fail(CommonConstant.FAIL);
    }

    @Override
    public Result delNotice(Long id) {
        return removeById(id) ? Result.ok(CommonConstant.SUCCESS) : Result.fail(CommonConstant.FAIL);
    }

    @Override
    public Result delBatch(String idsStr) {
        if (StrUtil.isBlank(idsStr)) {
            return Result.fail("至少请选择一个通知");
        }
        List<Long> ids = Arrays.stream(idsStr.split(StrUtil.COMMA)).map(Long::parseLong).collect(Collectors.toList());
        return removeByIds(ids) ? Result.ok(CommonConstant.SUCCESS) : Result.fail(CommonConstant.FAIL);
    }

    @Override
    public Result getNoticesByCondition(Integer currentPage, Integer pageSize, List<ConditionVo> conditions) {
        QueryWrapper<Notice> queryWrapper = SearchUtil.parseWhereSql(conditions);
        Page<Notice> page = baseMapper.selectPage(new Page<>(currentPage, pageSize), queryWrapper);
        PageList pageList = new PageList(page);
        pageList.setDataList(BeanUtil.copyToList(pageList.getDataList(), NoticeDto.class));
        return Result.ok(pageList);
    }
}
